﻿using System;
using System.Runtime.InteropServices;
using UnityEngine;

namespace UltimateFracturing
{
	// Token: 0x02000420 RID: 1056
	public static class ConcaveColliderInterface
	{
		// Token: 0x06001DD8 RID: 7640
		[DllImport("ConvexDecompositionDll")]
		private static extern void DllInit(bool bUseMultithreading);

		// Token: 0x06001DD9 RID: 7641
		[DllImport("ConvexDecompositionDll")]
		private static extern void DllClose();

		// Token: 0x06001DDA RID: 7642
		[DllImport("ConvexDecompositionDll")]
		private static extern void SetLogFunctionPointer(IntPtr pfnUnity3DLog);

		// Token: 0x06001DDB RID: 7643
		[DllImport("ConvexDecompositionDll")]
		private static extern void SetProgressFunctionPointer(IntPtr pfnUnity3DProgress);

		// Token: 0x06001DDC RID: 7644
		[DllImport("ConvexDecompositionDll")]
		private static extern void CancelConvexDecomposition();

		// Token: 0x06001DDD RID: 7645
		[DllImport("ConvexDecompositionDll")]
		private static extern bool DoConvexDecomposition(ref ConcaveColliderInterface.SConvexDecompositionInfoInOut infoInOut, Vector3[] pfVertices, int[] puIndices);

		// Token: 0x06001DDE RID: 7646
		[DllImport("ConvexDecompositionDll")]
		private static extern bool GetHullInfo(uint uHullIndex, ref ConcaveColliderInterface.SConvexDecompositionHullInfo infoOut);

		// Token: 0x06001DDF RID: 7647
		[DllImport("ConvexDecompositionDll")]
		private static extern bool FillHullMeshData(uint uHullIndex, ref float pfVolumeOut, int[] pnIndicesOut, Vector3[] pfVerticesOut);

		// Token: 0x06001DE0 RID: 7648 RVA: 0x000B75C8 File Offset: 0x000B57C8
		public static int ComputeHull(GameObject gameObject, FracturedObject fracturedObject)
		{
			int result = 0;
			if (!ConcaveColliderInterface.ComputeHull(gameObject, fracturedObject.ChunkColliderType == FracturedObject.ColliderType.Trigger, fracturedObject.ConcaveColliderAlgorithm, fracturedObject.ConcaveColliderMaxHulls, fracturedObject.ConcaveColliderMaxHullVertices, fracturedObject.ConcaveColliderLegacySteps, fracturedObject.Verbose, out result) && fracturedObject.ConcaveColliderAlgorithm == FracturedObject.ECCAlgorithm.Fast)
			{
				if (fracturedObject.Verbose)
				{
					Debug.Log(gameObject.name + ": Falling back to normal convex decomposition algorithm");
				}
				if (!ConcaveColliderInterface.ComputeHull(gameObject, fracturedObject.ChunkColliderType == FracturedObject.ColliderType.Trigger, FracturedObject.ECCAlgorithm.Normal, fracturedObject.ConcaveColliderMaxHulls, fracturedObject.ConcaveColliderMaxHullVertices, fracturedObject.ConcaveColliderLegacySteps, fracturedObject.Verbose, out result) && fracturedObject.Verbose)
				{
					Debug.Log(gameObject.name + ": Falling back to box collider");
				}
			}
			return result;
		}

		// Token: 0x06001DE1 RID: 7649 RVA: 0x000B7688 File Offset: 0x000B5888
		private static bool ComputeHull(GameObject gameObject, bool isTrigger, FracturedObject.ECCAlgorithm eAlgorithm, int nMaxHulls, int nMaxHullVertices, int nLegacySteps, bool bVerbose, out int nTotalTrianglesOut)
		{
			MeshFilter component = gameObject.GetComponent<MeshFilter>();
			ConcaveColliderInterface.DllInit(true);
			ConcaveColliderInterface.SetLogFunctionPointer(Marshal.GetFunctionPointerForDelegate(new ConcaveColliderInterface.LogDelegate(ConcaveColliderInterface.Log)));
			ConcaveColliderInterface.SConvexDecompositionInfoInOut sconvexDecompositionInfoInOut = default(ConcaveColliderInterface.SConvexDecompositionInfoInOut);
			nTotalTrianglesOut = 0;
			if (component && component.sharedMesh)
			{
				uint num = (uint)Mathf.Max(1, nLegacySteps);
				sconvexDecompositionInfoInOut.uMaxHullVertices = (uint)Mathf.Max(3, nMaxHullVertices);
				sconvexDecompositionInfoInOut.uMaxHulls = (uint)nMaxHulls;
				sconvexDecompositionInfoInOut.fPrecision = 0.2f;
				sconvexDecompositionInfoInOut.fBackFaceDistanceFactor = 0.2f;
				sconvexDecompositionInfoInOut.uLegacyDepth = ((eAlgorithm != FracturedObject.ECCAlgorithm.Legacy) ? 0U : num);
				sconvexDecompositionInfoInOut.uNormalizeInputMesh = 0U;
				sconvexDecompositionInfoInOut.uUseFastVersion = ((eAlgorithm != FracturedObject.ECCAlgorithm.Fast) ? 0U : 1U);
				sconvexDecompositionInfoInOut.uTriangleCount = (uint)(component.sharedMesh.triangles.Length / 3);
				sconvexDecompositionInfoInOut.uVertexCount = (uint)component.sharedMesh.vertexCount;
				Vector3[] vertices = component.sharedMesh.vertices;
				if (ConcaveColliderInterface.DoConvexDecomposition(ref sconvexDecompositionInfoInOut, vertices, component.sharedMesh.triangles))
				{
					for (int i = 0; i < sconvexDecompositionInfoInOut.nHullsOut; i++)
					{
						ConcaveColliderInterface.SConvexDecompositionHullInfo sconvexDecompositionHullInfo = default(ConcaveColliderInterface.SConvexDecompositionHullInfo);
						ConcaveColliderInterface.GetHullInfo((uint)i, ref sconvexDecompositionHullInfo);
						if (sconvexDecompositionHullInfo.nTriangleCount > 0)
						{
							Vector3[] array = new Vector3[sconvexDecompositionHullInfo.nVertexCount];
							int[] array2 = new int[sconvexDecompositionHullInfo.nTriangleCount * 3];
							float num2 = -1f;
							ConcaveColliderInterface.FillHullMeshData((uint)i, ref num2, array2, array);
							Mesh mesh = new Mesh();
							mesh.vertices = array;
							mesh.triangles = array2;
							mesh.uv = new Vector2[array.Length];
							mesh.RecalculateNormals();
							MeshCollider meshCollider = new GameObject("Hull " + (i + 1))
							{
								transform = 
								{
									position = gameObject.transform.position,
									rotation = gameObject.transform.rotation,
									localScale = gameObject.transform.localScale,
									parent = gameObject.transform
								},
								layer = gameObject.layer
							}.AddComponent<MeshCollider>();
							meshCollider.sharedMesh = null;
							meshCollider.sharedMesh = mesh;
							meshCollider.convex = true;
							meshCollider.isTrigger = isTrigger;
							nTotalTrianglesOut += sconvexDecompositionHullInfo.nTriangleCount;
						}
						else if (bVerbose)
						{
							Debug.LogWarning(gameObject.name + ": Error generating collider. ComputeHull() returned 0 triangles.");
						}
					}
					if (sconvexDecompositionInfoInOut.nHullsOut < 0 && bVerbose)
					{
						Debug.LogWarning(gameObject.name + ": Error generating collider. ComputeHull() returned no hulls.");
					}
				}
				else if (bVerbose)
				{
					Debug.LogWarning(gameObject.name + ": Error generating collider. ComputeHull() returned false.");
				}
			}
			ConcaveColliderInterface.DllClose();
			return nTotalTrianglesOut > 0;
		}

		// Token: 0x06001DE2 RID: 7650 RVA: 0x000195B1 File Offset: 0x000177B1
		private static void Log(string message)
		{
			Debug.Log(message);
		}

		// Token: 0x02000421 RID: 1057
		private struct SConvexDecompositionInfoInOut
		{
			// Token: 0x04001E00 RID: 7680
			public uint uMaxHullVertices;

			// Token: 0x04001E01 RID: 7681
			public uint uMaxHulls;

			// Token: 0x04001E02 RID: 7682
			public float fPrecision;

			// Token: 0x04001E03 RID: 7683
			public float fBackFaceDistanceFactor;

			// Token: 0x04001E04 RID: 7684
			public uint uLegacyDepth;

			// Token: 0x04001E05 RID: 7685
			public uint uNormalizeInputMesh;

			// Token: 0x04001E06 RID: 7686
			public uint uUseFastVersion;

			// Token: 0x04001E07 RID: 7687
			public uint uTriangleCount;

			// Token: 0x04001E08 RID: 7688
			public uint uVertexCount;

			// Token: 0x04001E09 RID: 7689
			public int nHullsOut;
		}

		// Token: 0x02000422 RID: 1058
		private struct SConvexDecompositionHullInfo
		{
			// Token: 0x04001E0A RID: 7690
			public int nVertexCount;

			// Token: 0x04001E0B RID: 7691
			public int nTriangleCount;
		}

		// Token: 0x02000423 RID: 1059
		// (Invoke) Token: 0x06001DE4 RID: 7652
		public delegate void LogDelegate([MarshalAs(UnmanagedType.LPStr)] string message);
	}
}
